package initialize

import (
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	"konglu-pay/global"
	"konglu-pay/validators"

	ent "github.com/go-playground/validator/v10/translations/en"
	zht "github.com/go-playground/validator/v10/translations/zh"
	"reflect"
	"strings"
)

func Translator() {
	// 初始化翻译validator
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		// 注册一个获取JSON的tag的定义方法
		v.RegisterTagNameFunc(func(field reflect.StructField) string {
			name := strings.SplitN(field.Tag.Get("json"), ",", 2)[0]
			if name == "_" {
				return ""
			}
			return name
		})
		// 第一个参数是备用的语言环境，后面是支持的语言环境
		uni := ut.New(en.New(), zh.New())
		validateTranslator, _ := uni.GetTranslator(global.Setting.ServerConfig.Locale)
		registerLocale(global.Setting.ServerConfig.Locale, v, validateTranslator)
		global.ValidateTranslator = validateTranslator
		registerCustomValidation(v, "mobile", "必须是11位手机号", validators.ValidateMobile)
		registerCustomValidation(v, "qq", "QQ号不合法", validators.ValidateQQ)
		registerCustomValidation(v, "big_decimal_money", "金额必须为数值，并且必须大于0", validators.ValidateBigDecimalMoney)
		registerCustomValidation(v, "face2face_timeout_express", "最晚付款时间不合法", validators.ValidateFace2faceTimeoutExpress)
	}
	global.Log.Info("register validator ok")
}

func registerLocale(locale string, v *validator.Validate, validateTranslator ut.Translator) {
	switch locale {
	case "en":
		_ = ent.RegisterDefaultTranslations(v, validateTranslator)
	case "zh":
		_ = zht.RegisterDefaultTranslations(v, validateTranslator)
	default:
		_ = ent.RegisterDefaultTranslations(v, validateTranslator)
	}
}

// registerCustomValidation 注册自定义验证器
func registerCustomValidation(v *validator.Validate, tag string, hint string, fn validator.Func) {
	_ = v.RegisterValidation(tag, fn)
	_ = v.RegisterTranslation(tag, global.ValidateTranslator, func(ut ut.Translator) error {
		return ut.Add(tag, hint, true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T(tag, fe.Field())
		return t
	})
}
